package cn.uncode.dal.interceptor;

import java.lang.reflect.Method;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.aop.framework.AopProxyUtils;
import org.springframework.aop.support.AopUtils;

import cn.uncode.dal.annotation.Database;
import cn.uncode.dal.annotation.DatabaseType;
import cn.uncode.dal.datasource.DBContextHolder;



public class RoutingDatabaseInterceptor implements MethodInterceptor{

	@Override
	public Object invoke(MethodInvocation invocation) throws Throwable {
        Method method = null;
        Class<?> clazz;
		if (AopUtils.isAopProxy(invocation.getThis())) {
			clazz = AopProxyUtils.ultimateTargetClass(invocation.getThis());
		} else {
			clazz = invocation.getMethod().getDeclaringClass();
		}
		Method[] methods = clazz.getDeclaredMethods();
		if(null != methods){
			for(Method md:methods){
				if(md.getName().equals(invocation.getMethod().getName())){
					method = md;
					break;
				}
			}
		}
		if(null != method){
			Database database = method.getAnnotation(Database.class);
			if(database != null){
				String custom = database.custom();
				if(StringUtils.isNotBlank(custom)){
					DBContextHolder.swithTo(custom);
				}else{
					DatabaseType vlu = database.value();
					if(vlu != null){
						if(DatabaseType.WRITE.equals(vlu)){
							DBContextHolder.swithToWrite();
						}else if(DatabaseType.READ.equals(vlu)){
							DBContextHolder.swithToRead();
						}else if(DatabaseType.TRANSACTION.equals(vlu)){
							DBContextHolder.swithTotransaction();
						}
					}
				}
			}
		}
        return invocation.proceed();
	}


}
